#include "ARPCommon.h"

#ifdef WIN32
#include "winsock.h" // for inet_addr
#pragma comment(lib, "ws2_32.lib")
#endif

#ifdef __BORLANDC__
#include "winsock.h"
#endif

using namespace arp;

// ----------------------------------------------------------------------------
// Mac
// ----------------------------------------------------------------------------
Mac::Mac()
{
	clear();
}

Mac::~Mac()
{
}

void Mac::clear()
{
	for (int i = 0; i < MAC_SIZE; i++)
		s[i] = 0;
}

Mac  Mac::operator =  (std::string s)
{
	int i;
	UINT8 ch1, ch2;
	UINT8 *p;

	p = (UINT8*)s.c_str();
	for (i = 0; i < MAC_SIZE; i++)
	{
		ch1 = *p++;
		if (ch1 >= 'a') ch1 = ch1 - 'a' + 'A';
		if (ch1 >= 'A')
			ch1 = ch1 - 'A' + 10;
		else
			ch1 = ch1 - '0';
		ch2 = *p++;
		if (ch2 >= 'a') ch2 = ch2 - 'a' + 'A';
		if (ch2 >= 'A')
			ch2 = ch2 - 'A' + 10;
		else
			ch2 = ch2 - '0';
		this->s[i] = (ch1 << 4) + ch2;
		while (*p == '-' || *p == ':') p++;
	}
	return *this;
}

Mac  Mac::operator =  (Mac& mac)
{
	for (int i = 0; i < MAC_SIZE; i++)
	{
		this->s[i] = mac.s[i];
	}
	return *this;
}

bool Mac::operator == (Mac& mac)
{
	for (int i = 0; i < MAC_SIZE; i++)
	{
		if (this->s[i] != mac.s[i])
			return false;
	}
	return true;
}

bool Mac::operator != (Mac& mac)
{
	for (int i = 0; i < MAC_SIZE; i++)
	{
		if (this->s[i] != mac.s[i])
			return true;
	}
	return false;
}

bool Mac::operator <  (Mac& mac)
{
	for (int i = 0; i < MAC_SIZE; i++)
	{
		if (this->s[i] == mac.s[i])
			continue;
		if (this->s[i] < mac.s[i])
			return true;
		else
			return false;
	}
	return false;
}

bool Mac::operator <= (Mac& mac)
{
	for (int i = 0; i < MAC_SIZE; i++)
	{
		if (this->s[i] == mac.s[i])
			continue;
		if (this->s[i] < mac.s[i])
			return true;
		else
			return false;
	}
	return true;
}

bool Mac::operator >  (Mac& mac)
{
	for (int i = 0; i < MAC_SIZE; i++)
	{
		if (this->s[i] == mac.s[i])
			continue;
		if (this->s[i] > mac.s[i])
			return true;
		else
			return false;
	}
	return false;
}

bool Mac::operator >= (Mac& mac)
{
	for (int i = 0; i < MAC_SIZE; i++)
	{
		if (this->s[i] == mac.s[i])
			continue;
		if (this->s[i] > mac.s[i])
			return true;
		else
			return false;
	}
	return true;
}

std::string Mac::toString()
{
	UINT8 ch1, ch2;
	int i, nIndex;
	char szBuffer[MAC_SIZE * 3]; // enough size
	
	nIndex = 0;
	for (i = 0; i < MAC_SIZE; i++)
	{
		ch1 = s[i] & 0xF0;
		ch1 = ch1 >> 4;
		if (ch1 > 9)
			ch1 = ch1 + 'A' - 10;
		else
			ch1 = ch1 + '0';
		ch2 = s[i] & 0x0F;
		if (ch2 > 9)
			ch2 = ch2 + 'A' - 10;
		else
			ch2 = ch2 + '0';
		szBuffer[nIndex++] = ch1;
		szBuffer[nIndex++] = ch2;
		if (i == 2)
			szBuffer[nIndex++] = '-';
	}
	szBuffer[nIndex] = '\0';
	return (std::string(szBuffer));
}

// ----------------------------------------------------------------------------
// Ip
// ----------------------------------------------------------------------------
Ip::Ip()
{
	clear();
}

Ip::~Ip()
{
}

void Ip::clear()
{
	for (int i = 0; i < IP_SIZE; i++)
	{
		s[i] = 0;
	}
}

Ip   Ip::operator =  (std::string s)
{
	unsigned long l = inet_addr(s.c_str());
	memcpy(this->s, &l, IP_SIZE);
	return *this;
}

Ip   Ip::operator =  (Ip& ip)
{
	for (int i = 0; i < IP_SIZE; i++)
	{
		this->s[i] = ip.s[i];
	}
	return *this;
}

bool Ip::operator == (Ip& ip)
{
	for (int i = 0; i < IP_SIZE; i++)
	{
		if (this->s[i] != ip.s[i])
			return false;
	}
	return true;
}

bool Ip::operator != (Ip& ip)
{
	for (int i = 0; i < IP_SIZE; i++)
	{
		if (this->s[i] != ip.s[i])
			return true;
	}
	return false;
}

bool Ip::operator <  (Ip& ip)
{
	for (int i = 0; i < IP_SIZE; i++)
	{
		if (this->s[i] == ip.s[i])
			continue;
		if (this->s[i] < ip.s[i])
			return true;
		else
			return false;
	}
	return false;
}

bool Ip::operator <= (Ip& ip)
{
	for (int i = 0; i < IP_SIZE; i++)
	{
		if (this->s[i] == ip.s[i])
			continue;
		if (this->s[i] < ip.s[i])
			return true;
		else
			return false;
	}
	return true;
}

bool Ip::operator >  (Ip& ip)
{
	for (int i = 0; i < IP_SIZE; i++)
	{
		if (this->s[i] == ip.s[i])
			continue;
		if (this->s[i] > ip.s[i])
			return true;
		else
			return false;
	}
	return false;
}

bool Ip::operator >= (Ip& ip)
{
	for (int i = 0; i < IP_SIZE; i++)
	{
		if (this->s[i] == ip.s[i])
			continue;
		if (this->s[i] > ip.s[i])
			return true;
		else
			return false;
	}
	return true;
}

std::string Ip::toString()
{
	std::string s;
	char szTemp[255]; // enough size

	sprintf(szTemp, "%d.%d.%d.%d", this->s[0], this->s[1], this->s[2], this->s[3]);
	s = szTemp;
	return s;
}

int  Ip::toInt()
{
	unsigned long *l = (unsigned long*)s;
	return ntohl(*s);
}